import datetime
import time
from typing import Union


def formatter_datetime(res, datetime_formatter: str = None, unit: str = "millisecond"):
    if isinstance(res, datetime.date) \
            or isinstance(res, datetime.time) \
            or isinstance(res, datetime.datetime):
        if not datetime_formatter:
            datetime_formatter = "datetime"

        if datetime_formatter not in ["datetime", "iso8601", "str", "long"]:
            error_msg = f"不支持当前时间格式化类型 {datetime_formatter}"
            raise RuntimeWarning(error_msg)
        if "datetime" == datetime_formatter:
            return res
        elif "iso8601" == datetime_formatter:
            return formatter_datetime_2_iso8601(res)
        elif "str" == datetime_formatter:
            return formatter_datetime_2_str(res)
        elif "long" == datetime_formatter:
            return formatter_datetime_2_timestamp(res, unit)
        else:
            return res
    else:
        return res


def formatter_datetime_2_str(t: Union[datetime.date, datetime.time, datetime.datetime]):
    if isinstance(t, datetime.datetime):
        return t.strftime("%Y-%m-%d %H:%M:%S")
    elif isinstance(t, datetime.time):
        return t.strftime('%H:%M:%S')
    elif isinstance(t, datetime.date):
        return t.strftime("%Y-%m-%d")


def formatter_datetime_2_iso8601(t: Union[datetime.date, datetime.time, datetime.datetime]):
    return t.isoformat()


def formatter_datetime_2_timestamp(t: Union[datetime.date, datetime.time, datetime.datetime], unit: str):
    if "second" == unit:
        if t:
            if isinstance(t, datetime.date):
                return datetime.datetime(t.year, t.month, t.day).timestamp()
            else:
                return int(t.timestamp())
        else:
            return None
    elif "millisecond" == unit:
        if t:
            try:
                if isinstance(t, datetime.date):
                    return int(datetime.datetime.fromordinal(t.toordinal()).timestamp() * 1000)
                else:
                    return int(t.timestamp() * 1000)
            except OSError:
                print(f"出问题的时间是 {t}")
                return None
        else:
            return None
    else:
        raise RuntimeWarning("暂只支持 转换为 秒 或 毫秒")


def parser_long_2_datetime(ts: int, unit: str):
    if "second" == unit:
        time_array = time.localtime(ts)  # 1970秒数
    elif "millisecond" == unit:
        time_array = time.localtime(ts // 1000)  # 1970秒数
    else:
        raise RuntimeWarning("暂只支持 转换为 秒 或 毫秒")
    other_style_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
    return datetime.datetime.strptime(other_style_time, "%Y-%m-%d %H:%M:%S")


def parser_str_2_datetime(d_s: str, formatter: str = "%Y-%m-%d %H:%M:%S"):
    return datetime.datetime.strptime(d_s, formatter)


def transfer_str_2_long(d_s: str, unit: str):
    dt = parser_str_2_datetime(d_s)
    return formatter_datetime_2_timestamp(dt, unit)


def get_now_str():
    now = datetime.datetime.now()
    return f"{now.year}{now.month}{now.day}{now.hour}{now.minute}{now.second}{now.microsecond}"


def get_now_month_day_str():
    now = datetime.datetime.now()
    month = f"0{now.month}" if now.month < 10 else f"{now.month}"
    day = f"0{now.day}" if now.day < 10 else f"{now.day}"
    return f"{month}{day}"


def convert_date_str_long(date_str: str, formatter: str = "%Y-%m-%d %H:%M:%S"):
    start_datetime = parser_str_2_datetime(date_str, formatter=formatter)
    return formatter_datetime(start_datetime, "long")


if __name__ == "__main__":
    t = datetime.datetime.now()
    print(t)
    ds = time.mktime(t.timetuple())
    print(ds)
    st = formatter_datetime_2_timestamp(t, "millisecond")
    print(st)
